<!--
/**
 * author: vformAdmin
 * email: vdpadmin@163.com
 * website: https://www.vform666.com
 * date: 2021.08.18
 * remark: 如果要分发VForm源码，需在本文件顶部保留此文件头信息！！
 */
-->
<template>
  <el-container class="form-designer-container full-height" >
    <el-header class="form-designer-header" v-if="showHeader">
      <div class="header-left">
        <span>{{ i18nt('application.productTitle') }}</span>
        <span class="version-span">（{{vFormVersion}}）</span>
      </div>
      <div class="header-right">
        <a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, gitUrl)" target="_blank"><VfIcon name="github" color="#008df0"/>{{i18nt('application.github')}}</a>
        <a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, docUrl)" target="_blank"><VfIcon name="document" color="#008df0"/>{{i18nt('application.document')}}</a>
        <a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, chatUrl)" target="_blank">{{i18nt('application.qqGroup')}}</a>
        <a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, subScribeUrl)" target="_blank">{{i18nt('application.subscription')}}</a>
      </div>
    </el-header>

    <el-container :class="['form-designer-center']">
      <!-- 左侧组件选择面板 -->
      <el-aside :class="['form-designer-aside-left', leftAsideHidden ? 'hidden': '' ]">
        <widget-panel :designer="designer"/>
      </el-aside>
      <div :class="[ 'aside-toggle-left', leftAsideHidden ? 'hidden': '' ]" @click="leftAsideHidden = !leftAsideHidden">
        <el-icon class="toggle-icon">
          <el-icon-care-right v-if="leftAsideHidden"/>
          <el-icon-care-left v-else/>
        </el-icon>
      </div>
      <!-- 设计主区域 -->
      <el-container class="designer-center-container">
        <el-header class="toolbar-header">
          <toolbar-panel
            ref="toolbarRef"
            :designer="designer"
            :global-dsv="globalDsv"
          >
            <!-- 自定义插槽配置 -->
            <template v-for="(idx, slotName) in $slots" #[slotName]>
              <slot :name="slotName"></slot>
            </template>
          </toolbar-panel>
        </el-header>
        <el-main id="formWidgetMain" class="form-widget-main" >
          <el-scrollbar class="center-scrollbar">
            <v-form-widget
              ref="formRef"
              :designer="designer"
              :minHeight="formWidgetMinHeight"
              :global-dsv="globalDsv"
              :form-config="designer.formConfig"
            >
            </v-form-widget>
          </el-scrollbar>
        </el-main>
      </el-container>
      <!-- 右侧配置设置面板 -->
      <el-aside :class="['form-designer-aside-right', rightAsideHidden ? 'hidden': '' ]">
        <setting-panel
          :designer="designer"
          :global-dsv="globalDsv"
          :form-config="designer.formConfig"
          :selected-widget="designer.selectedWidget"
          @edit-event-handler="testEEH"
        />
      </el-aside>
      <div
        :class="[
          'aside-toggle-right',
          rightAsideHidden ? 'hidden': ''
        ]"
        @click="rightAsideHidden = !rightAsideHidden">
        <el-icon class="toggle-icon">
          <el-icon-care-left v-if="rightAsideHidden"/>
          <el-icon-care-right v-else/>
        </el-icon>
      </div>
    </el-container>

  </el-container>
</template>

<script>
import axios from 'axios'

import WidgetPanel from './widget-panel/WidgetPanel.vue'
import VFormWidget from './form-widget/index'
import ToolbarPanel from './toolbar-panel/index'
import SettingPanel from './setting-panel/index'

import i18n, { changeLocale } from "@/utils/i18n"
import { createDesigner } from "@/components/form-designer/designer"
import {
  addWindowResizeHandler, deepClone, getQueryParam,
  getAllContainerWidgets, getAllFieldWidgets, traverseAllWidgets
} from "@/utils/util"

import { TokenUtils, AUTH_CONS } from '@/utils/auth/index.js'
import { VfMessage } from '@/utils/vf-utils'
import { MOCK_CASE_URL, VARIANT_FORM_VERSION } from "@/utils/config"
import { DEFAULT_AXIOS_CONFIG, DEFAULT_DESIGNER_CONFIG } from '@/constant/constant-settings'


export default {
  name: "VFormDesigner",
  componentName: "VFormDesigner",
  mixins: [i18n],
  components: {
    WidgetPanel,
    ToolbarPanel,
    SettingPanel,
    VFormWidget,
  },
  props: {
    /* 全局数据源变量 */
    globalDsv: { type: Object, default: () => ({}) },
    /* 后端字段列表API */
    fieldListApi: { type: Object, default: null },
    /* 禁止显示的组件名称数组 */
    bannedWidgets: { type: Array, default: () => [] },
    /* 设计器配置信息 */
    designerConfig: { type: Object, default: () => { return DEFAULT_DESIGNER_CONFIG } },
    /* TODO 是否显示编辑器头部 */
    showHeader: { type: Boolean, default: false },
    /* TODO 业务相关配置信息 */
    busiConfig: { type: Object, default: () => { return { userInfo: {}, dataHouse: {} } } },
    /* TODO axios请求配置 */
    axiosConfig: { type: Object, default: () => { return DEFAULT_AXIOS_CONFIG } },
    /* TODO 插槽选择数据 */
    slotsConfig: { type: Object, default: () => { return { dataPools: [] } }},
    /* TODO 枚举数据配置 */
    enumsConfig: { type: Object, default: () => { return { dataPools: [] } }}
  },
  data() {
    return {
      // 国际化
      curLocale: '',
      // 国际化语言
      curLangName: '',

      // 模版名称
      caseName: '',
      vsCodeFlag: false,
      // 版本号
      vFormVersion: VARIANT_FORM_VERSION,

      docUrl: 'https://www.vform666.com/document3.html',
      gitUrl: 'https://github.com/vform666/variant-form3-vite',
      chatUrl: 'https://www.vform666.com/pages/chat-group/',
      subScribeUrl: 'https://www.vform666.com/pages/pro/',

      // 设计器操作
      designer: createDesigner(this),
      // name字段下拉数据
      fieldList: [],
      
      // 滚动高度
      scrollerHeight: 0,

      // TODO-NEW 左侧面板隐藏
      leftAsideHidden: false,
      // TODO-NEW 右侧面板隐藏
      rightAsideHidden: false,
      // TODO 设计主区域的最小高度
      formWidgetMinHeight: 200,
    }
  },
  provide() {
    return {
      // 提供控制面板隐藏状态的方法
      setLeftAsideHidden: (hidden) => {
        this.leftAsideHidden = hidden;
      },
      setRightAsideHidden: (hidden) => {
        this.rightAsideHidden = hidden;
      },
      getLeftAsideHidden: () => this.leftAsideHidden,
      getRightAsideHidden: () => this.rightAsideHidden,
      busiConfig: this.busiConfig,
      axiosConfig: this.axiosConfig,
      slotFieldList: this.slotsConfig.dataPools,
      enumsDataPools: this.enumsConfig.dataPools,
      serverFieldList: this.fieldList,
      getBannedWidgets: () => this.bannedWidgets,
      getDesignerConfig: () => {
        return {
          ...DEFAULT_DESIGNER_CONFIG,
          ...this.designerConfig
        }
      },
    }
  },
  created() {
    this.vsCodeFlag = getQueryParam('vscode') == 1
    this.caseName = getQueryParam('case')
    this.initAxiosConfig()
  },
  mounted() {
    // 初始化国际化
    this.initLocale()
    // 加载模板
    this.loadCase()
    // 计算设计区域高度
    this.calcWidgetHeight()
    // 加载字段选项数据
    this.loadFieldListFromServer()
  },
  methods: {
    // 初始化请求配置
    initAxiosConfig () {
      const { axiosConfig } = this
      const { token } = axiosConfig
      if (token) { TokenUtils.setAuthorization(token) }
    },
    calcWidgetHeight() {
      this.$nextTick(() => {
        const formWidgetMainDom = document.getElementById('formWidgetMain')
        const formWidgetMainHeight = formWidgetMainDom.offsetHeight
        const formWidgetMinHeight = formWidgetMainHeight - 26 - 6
        this.formWidgetMinHeight = formWidgetMinHeight
      })
    },
    /**
     * 是否显示外链
     * 
     * @param configName 配置属性，默认值为：externalLink
     */
    showLink(configName='externalLink') {
      if (this.designerConfig[configName] === undefined) {
        return true
      }
      return !!this.designerConfig[configName]
    },

    testEEH(eventName, eventParams) {
      console.log('test', eventName)
      console.log('test222222', eventParams)
    },

    openUrl(event, url) {
      if (!!this.vsCodeFlag) {
        const msgObj = {
          cmd: 'openUrl',
          data: {
            url
          }
        }
        window.parent.postMessage(msgObj, '*')
      } else {
        let aDom = event.currentTarget
        aDom.href = url
        //window.open(url, '_blank') //直接打开新窗口，会被浏览器拦截
      }
    },

    loadCase() {
      if (!this.caseName) {
        return
      }

      axios.get(MOCK_CASE_URL + this.caseName + '.txt').then(res => {
        if (!!res.data.code) {
          VfMessage.error(this.i18nt('designer.hint.sampleLoadedFail'))
          return
        }

        this.setFormJson(res.data)
        VfMessage.success(this.i18nt('designer.hint.sampleLoadedSuccess'))
      }).catch(error => {
        VfMessage.error(this.i18nt('designer.hint.sampleLoadedFail') + ':' + error)
      })
    },

    initLocale() {
      this.curLocale = localStorage.getItem('v_form_locale')
      if (!!this.vsCodeFlag) {
        this.curLocale = this.curLocale || 'en-US'
      } else {
        this.curLocale = this.curLocale || 'zh-CN'
      }
      this.curLangName = this.i18nt('application.' + this.curLocale)
      changeLocale(this.curLocale)
    },
    loadFieldListFromServer() {
      if (!this.fieldListApi) {
        return
      }

      let headers = this.fieldListApi.headers || {}
      axios.get(this.fieldListApi.URL, {'headers': headers}).then(res => {
        let labelKey = this.fieldListApi.labelKey || 'label'
        let nameKey = this.fieldListApi.nameKey || 'name'

        this.fieldList.splice(0, this.fieldList.length)  //清空已有
        res.data.forEach(fieldItem => {
          this.fieldList.push({
            label: fieldItem[labelKey],
            name: fieldItem[nameKey]
          })
        })
      }).catch(error => {
        VfMessage.error(error)
      })
    },
    /**
     * 切换语言模式
     * @param command 语言模式
     */
    switchLanguage(command) {
      changeLocale(command)
      this.curLangName = this.i18nt('application.' + command)
    },
    
    /**
     * 设置导入JSON按钮的显示状态
     * @param state {Boolean} true 显示按钮，false 隐藏按钮
     */
    setImportJsonButton(state) {
      this.$refs.toolbarRef.setImportJsonButton(state);
    },

    /**
     * 隐藏导出按钮
     * @param true/false
     */
    setExportJsonButton(state) {
      this.$refs.toolbarRef.setExportJsonButton(state);
    },
    setFormJson(formJson) {
      let modifiedFlag = false
      if (!!formJson) {
        if (typeof formJson === 'string') {
          modifiedFlag = this.designer.loadFormJson(JSON.parse(formJson) )
        } else if (formJson.constructor === Object) {
          modifiedFlag = this.designer.loadFormJson(formJson)
        }

        if (modifiedFlag) {
          this.designer.emitHistoryChange()
        }
      }
    },
    getFormJson() {
      return {
        widgetList: deepClone(this.designer.widgetList),
        formConfig: deepClone(this.designer.formConfig)
      }
    },

    clearDesigner() {
      this.$refs.toolbarRef.clearFormWidget()
    },


    /**
     * 刷新表单设计器
     */
    refreshDesigner() {
      //this.designer.loadFormJson( this.getFormJson() )  //只有第一次调用生效？？

      let fJson = this.getFormJson()
      this.designer.clearDesigner(true)  //不触发历史记录变更
      this.designer.loadFormJson(fJson)
    },

    /**
     * 预览表单
     */
    previewForm() {
      this.$refs.toolbarRef.previewForm()
    },

    /**
     * 导入表单JSON
     */
    importJson() {
      this.$refs.toolbarRef.importJson()
    },

    /**
     * 导出表单JSON
     */
    exportJson() {
      this.$refs.toolbarRef.exportJson()
    },

    /**
     * 导出Vue/HTML代码
     */
    exportCode() {
      this.$refs.toolbarRef.exportCode()
    },

    /**
     * 生成SFC代码
     */
    generateSFC() {
      this.$refs.toolbarRef.generateSFC()
    },

    /**
     * 获取所有字段组件
     * @returns {*[]}
     */
    getFieldWidgets(widgetList = null) {
      return !!widgetList ? getAllFieldWidgets(widgetList) : getAllFieldWidgets(this.designer.widgetList)
    },

    /**
     * 获取所有容器组件
     * @returns {*[]}
     */
    getContainerWidgets(widgetList = null) {
      return !!widgetList ? getAllContainerWidgets(widgetList) : getAllContainerWidgets(this.designer.widgetList)
    },

    /**
     * 升级表单json，以补充最新的组件属性
     * @param formJson
     */
    upgradeFormJson(formJson) {
      if (!formJson.widgetList || !formJson.formConfig) {
        VfMessage.error('Invalid form json!')
        return
      }

      traverseAllWidgets(formJson.widgetList, (w) => {
        this.designer.upgradeWidgetConfig(w)
      })
      this.designer.upgradeFormConfig(formJson.formConfig)

      return formJson
    },

    getWidgetRef(widgetName, showError = false) {
      return this.$refs['formRef'].getWidgetRef(widgetName, showError)
    },

    getSelectedWidgetRef() {
      return this.$refs['formRef'].getSelectedWidgetRef()
    },

    //TODO: 增加更多方法！！
  }
}
</script>

<style lang="scss" scoped>
@import './index.scss';
</style>
